package com.atguigu.tingshu.common.config;

import com.atguigu.tingshu.common.constant.RabbitConstant;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;

import java.util.concurrent.TimeUnit;

@Configuration
@Slf4j
public class RabbitConfig {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    // 创建延迟队列 + 死信队列

    @Bean
    public Exchange cancelOrderExchange() {
        // 创建一个交换机
        return ExchangeBuilder
                .topicExchange(RabbitConstant.ORDER_EXCHANGE)
                .durable(true)
                .build();
    }

    // 创建队列
    @Bean
    public Queue cancelOrderQueue() {
        // 创建一个队列
        return QueueBuilder
                .durable(RabbitConstant.ORDER_TTL_QUEUE)
                .ttl(RabbitConstant.ORDER_CANCEL_TIME)// 配置死信交换机 和 死信队列
                .deadLetterExchange(RabbitConstant.ORDER_EXCHANGE)
                .deadLetterRoutingKey(RabbitConstant.ORDER_DEAD_RK)
                .build();
    }

    // 绑定交换机与队列
    // 通过方法参数 直接注入对象 可以直接使用对象
    @Bean
    public Binding cancelOrderBinding(Exchange cancelOrderExchange, Queue cancelOrderQueue) {
        return BindingBuilder
                .bind(cancelOrderQueue)
                .to(cancelOrderExchange)
                .with(RabbitConstant.ORDER_TTL_RK)
                .noargs();
    }

    // 创建死信队列和死信交换机 并绑定关系

    @Bean
    public Queue deadOrderQueue() {
        // 创建一个队列
        return QueueBuilder
                .durable(RabbitConstant.ORDER_DEAD_QUEUE)
                .build();
    }
    // 复用了交换机
//    @Bean
//    public Exchange deadOrderExchange() {
//        // 创建一个交换机
//        return ExchangeBuilder
//                .topicExchange(RabbitConstant.ORDER_EXCHANGE)
//                .durable(true)
//                .build();
//    }
    @Bean
    public Binding deadOrderBinding(Exchange cancelOrderExchange, Queue deadOrderQueue) {
        return BindingBuilder
                .bind(deadOrderQueue)
                .to(cancelOrderExchange)
                .with(RabbitConstant.ORDER_DEAD_RK)
                .noargs();
    }







    @PostConstruct
    public void init() {
        // 确认消息是否到达交换机，无论是否到达都会执行
        this.rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (!ack) {
                log.error("消息没有到达交换机。原因：{}", cause);
            }
        });
        // 确认消息是否到达队列，只有未到达队列才会执行
        this.rabbitTemplate.setReturnsCallback(returned -> {
            log.error("消息没有到达队列。交换机：{}，路由键：{}，消息：{}",
                    returned.getExchange(), returned.getRoutingKey(), new String(returned.getMessage().getBody()));
        });
    }
}
